﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

public class MapManager
{
    private int[,] map;
    private int sizex = 0, sizey = 0;
    private List<Texture2D> tile;
    private ContentManager content;
    private int mapNumber;
    int day;

    public int MapNumber
    {
        get { return mapNumber; }
    }

    public MapManager(ContentManager content)
    {
        this.content = content;
        tile = new List<Texture2D>();
        tile.Add(content.Load<Texture2D>("Textures/Map/dayzero"));
        tile.Add(content.Load<Texture2D>("Textures/Map/tiles"));
        tile.Add(content.Load<Texture2D>("Textures/Map/tilesday2"));
        tile.Add(content.Load<Texture2D>("Textures/Map/tilesday2"));
    }

    public void LoadMap(string day, int dayn, int mapNumber)
    {
        this.day = dayn;
        this.mapNumber = mapNumber;

        string path = "Content/Days/" + day + "/Map/" + mapNumber + ".txt";

        TextReader tr = new StreamReader(path);

        // read a line of text
        string aux1 = tr.ReadLine();
        string[] aux = aux1.Split(' ');
        sizex = Int32.Parse(aux[0]);
        sizey = Int32.Parse(aux[1]);

        map = new int[sizex, sizey];

        for (int i = 0; i < sizey; i ++ )
        {
            aux1 = tr.ReadLine();
            aux = aux1.Split(' ');
            for (int j = 0; j < sizex; j++)
            {
                string str = aux[j];
                int num = -1;
                if (str.Equals("AA"))
                    num = 100;
                else
                    num = int.Parse(str);

                map[j, i] = num;
            }

        }        

        // close the stream
        tr.Close();
    }

    int x, y;

    public void Draw(SpriteBatch spriteBatch, int x, int y)
    {
        this.x = x; this.y = y;

        int xpor64 = (int)x / 64;
        int ypor64 = (int)y / 64;

        int ydivi = 7, xdivi = 11;

        int x1, x2, y1, y2;

        if (xpor64 - xdivi >= 0)
            x1 = xpor64 - xdivi;
        else
            x1 = 0;

        if (ypor64 - ydivi >= 0)
            y1 = ypor64 - ydivi;
        else
            y1 = 0;

        if (xpor64 + xdivi <= sizex)
            x2 = xpor64 + xdivi;
        else
            x2 = sizex;

        if (ypor64 + ydivi <= sizey)
            y2 = ypor64 + ydivi;
        else
            y2 = sizey;

        int tilesize = 64;

        if (Globals.CheckingMap)
        {
            x1 = 0; x2 = sizex; y1 = 0; y2 = sizey; tilesize = 14;
        }
        //Console.WriteLine(x1 + " " + x2 + " " + y1 + " " + y2 + " " + xpor64 + " " + ypor64);

        for(int i = y1; i < y2; i++)
            for (int j = x1; j < x2; j++)
            {
                if (map[j, i] != 0)
                {
                    int tilenum = map[j, i] - 1;
                    int num = tile[day].Width / 64;
                    int yy = tilenum / num;
                    int xx = tilenum - yy * num;
                    //spriteBatch.Draw(GameSession.Tiles, new Vector2(i * 64, j * 64 + GameSession.screenAdjustment), new Rectangle(xtile * 64, ytile * 64, 64, 64), Color.White);
                    
                    if(
                        !(day == (int)Day.ONE && (map[j, i] == 79 ||map[j, i] == 80 || map[j, i] == 81 || map[j, i] == 82 || map[j, i] == 87 || map[j, i] == 88 || map[j, i] == 89 || map[j, i] == 90 ||  map[j, i] == 93 || map[j, i] == 94 || map[j, i] == 96 || map[j, i] == 97))
                        &&
                        !(day == (int)Day.TWO && map[j,i] >= 88)
                        )
                        spriteBatch.Draw(tile[day], new Rectangle(j * tilesize + Globals.ScreenWidth2 - x, i * tilesize + Globals.ScreenHeight2 - y, tilesize, tilesize), new Rectangle(0, 0, 64, 64), Color.White);
                    spriteBatch.Draw(tile[day], new Rectangle(j * tilesize + Globals.ScreenWidth2 - x, i * tilesize + Globals.ScreenHeight2 - y, tilesize, tilesize), new Rectangle(xx * 64, yy * 64, 64, 64), Color.White);
                }
            }

    }    

    public bool CheckCollision(Rectangle position)
    {
        int aux = (position.X + 1 ) / 64;
        int auy = (position.Y + 1) / 64;
        int aux2 = (position.X + position.Width - 1 ) / 64;
        int auy2 = (position.Y + position.Height - 1) / 64;
        
        //Console.WriteLine(aux + " " + auy + " " + aux2 + " " + auy2);

        if (aux < 0 || auy < 0 || aux2 < 0 || auy2 < 0
            || aux >= sizex || auy >= sizey || aux2 >= sizex || auy2 >= sizey || position.X < 0 || position.Y < 0)
            return true;

        int xcol = 0, ycol = 0;
        bool col = false;

        if (map[aux, auy] == 0 || map[aux2, auy] == 0 || map[aux, auy2] == 0 || map[aux2, auy2] == 0)
            return true;

        if (
            (map[aux, auy] != 1 && day != (int)Day.TWO) ||
            (map[aux, auy] != 32 && map[aux, auy] != 1 && map[aux, auy] != 8 && day == (int)Day.TWO))
        {
            xcol = aux; ycol = auy;
            int tilenum = map[xcol, ycol] - 1;
            int num = tile[day].Width / 64;
            int yy = tilenum / num;
            int xx = tilenum - yy * num;

            Color[] tileTextureData = new Color[64 * 64];
            tile[day].GetData(0, new Rectangle(xx * 64, yy * 64, 64, 64), tileTextureData, 0, 64 * 64);

            col = IntersectPixels(new Rectangle(xcol * 64 /*+ Globals.ScreenWidth2 - x*/, 
                ycol * 64 /*+ Globals.ScreenHeight2 - y*/, 64, 64), tileTextureData, position, GameSession.Player.PersonTextureData);

            if (col) return true;
            //return true;
        }

        if ((map[aux2, auy] != 1 && day != (int)Day.TWO) ||
            (map[aux2, auy] != 32 && map[aux2, auy] != 1 && map[aux2, auy] != 8 && day == (int)Day.TWO))
        {
            xcol = aux2; ycol = auy;
            int tilenum = map[xcol, ycol] - 1;
            int num = tile[day].Width / 64;
            int yy = tilenum / num;
            int xx = tilenum - yy * num;

            Color[] tileTextureData = new Color[64 * 64];
            tile[day].GetData(0, new Rectangle(xx * 64, yy * 64, 64, 64), tileTextureData, 0, 64 * 64);

            col = IntersectPixels(new Rectangle(xcol * 64 /*+ Globals.ScreenWidth2 - x*/, 
                ycol * 64 /*+ Globals.ScreenHeight2 - y*/, 64, 64), tileTextureData, position, GameSession.Player.PersonTextureData);

            if (col) return true;
            //return true;
        }

        if ((map[aux, auy2] != 1 && day != (int)Day.TWO) ||
            (map[aux, auy2] != 32 && map[aux, auy2] != 1 && map[aux, auy2] != 8 && day == (int)Day.TWO))
        {
            xcol = aux; ycol = auy2;
            int tilenum = map[xcol, ycol] - 1;
            int num = tile[day].Width / 64;
            int yy = tilenum / num;
            int xx = tilenum - yy * num;

            Color[] tileTextureData = new Color[64 * 64];
            tile[day].GetData(0, new Rectangle(xx * 64, yy * 64, 64, 64), tileTextureData, 0, 64 * 64);

            col = IntersectPixels(new Rectangle(xcol * 64 /*+ Globals.ScreenWidth2 - x*/,
                ycol * 64 /*+ Globals.ScreenHeight2 - y*/, 64, 64), tileTextureData, position, GameSession.Player.PersonTextureData);

            if (col) return true;//return true;
        }

        if ((map[aux2, auy2] != 1 && day != (int)Day.TWO) ||
            (map[aux2, auy2] != 32 && map[aux2, auy2] != 1 && map[aux2, auy2] != 8 && day == (int)Day.TWO))
        {
            xcol = aux2; ycol = auy2;
            int tilenum = map[xcol, ycol] - 1;
            int num = tile[day].Width / 64;
            int yy = tilenum / num;
            int xx = tilenum - yy * num;

            Color[] tileTextureData = new Color[64 * 64];
            tile[day].GetData(0, new Rectangle(xx * 64, yy * 64, 64, 64), tileTextureData, 0, 64 * 64);

            col = IntersectPixels(new Rectangle(xcol * 64 /*+ Globals.ScreenWidth2 - x*/,
                ycol * 64 /*+ Globals.ScreenHeight2 - y*/, 64, 64), tileTextureData, position, GameSession.Player.PersonTextureData);

            if (col) return true;//return true;
        }

        //CheckMapChange(position);

        return false;
    }

    public bool IntersectPixels(Rectangle rectangleA, Color[] dataA, Rectangle rectangleB, Color[] dataB)
    {
        int top = Math.Max(rectangleA.Top, rectangleB.Top);
        int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
        int left = Math.Max(rectangleA.Left, rectangleB.Left);
        int right = Math.Min(rectangleA.Right, rectangleB.Right);

        for (int y = top; y < bottom; y++)
        {
            for (int x = left; x < right; x++)
            {
                Color colorA = dataA[(x - rectangleA.Left) +
                                     (y - rectangleA.Top) * rectangleA.Width];
                Color colorB = dataB[(x - rectangleB.Left) +
                                     (y - rectangleB.Top) * rectangleB.Width];

                if (colorA.A != 0 && colorB.A != 0)
                {
                    return true;
                }
            }
        }
        return false;
    }

    private void CheckMapChange(Rectangle position)
    {
        int aux = (position.X + 1) / 64;
        int auy = (position.Y + 1) / 64;
        int aux2 = (position.X + position.Width - 1) / 64;
        int auy2 = (position.Y + position.Height - 1) / 64;

        //Console.WriteLine(aux + " " + auy);

        if ((aux == 3 || aux == 4) && auy == 9 && mapNumber == 0)
        {
            GameSession.ChangeMap(1);
        }
        if ((aux == 3 || aux == 4) && auy == 0 && mapNumber == 1)
        {
            GameSession.ChangeMap(0);
        }
    }
}